rect.width,
rect.height,
cairo_image_surface_get_stride (tmp),
+ GDK_MEMORY_DEFAULT,
target);
cairo_surface_unmap_image (surface, tmp);
#include "gdkglcontextprivate.h"
#include "gdkdisplayprivate.h"
+#include "gdkmemorytextureprivate.h"
#include "gdkinternals.h"
#include "gdkintl.h"
int width,
int height,
int stride,
+ GdkMemoryFormat data_format,
guint texture_target)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
+ guchar *copy = NULL;
+ guint gl_format;
+ guint gl_type;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
+ if (priv->use_es)
+ {
+ /* GLES only supports rgba, so convert if necessary */
+ if (data_format != GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
+ {
+ copy = g_malloc (width * height * 4);
+ gdk_memory_convert (copy, width * 4,
+ GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+ data, stride, data_format,
+ width, height);
+ stride = width * 4;
+ data = copy;
+ }
+
+ gl_format = GL_RGBA;
+ gl_type = GL_UNSIGNED_BYTE;
+ }
+ else
+ {
+ if (data_format == GDK_MEMORY_DEFAULT) /* Cairo surface format */
+ {
+ gl_format = GL_BGRA;
+ gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+ else /* Fall-back, convert to cairo-surface-format */
+ {
+ copy = g_malloc (width * height * 4);
+ gdk_memory_convert (copy, width * 4,
+ GDK_MEMORY_DEFAULT,
+ data, stride, data_format,
+ width, height);
+ stride = width * 4;
+ data = copy;
+ gl_format = GL_BGRA;
+ gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+ }
+
+
/* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
* the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
*/
- if (!priv->use_es ||
- (priv->use_es && (priv->gl_version >= 30 || priv->has_unpack_subimage)))
+ if (stride == width * 4)
+ {
+ glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, data);
+ }
+ else if (!priv->use_es ||
+ (priv->use_es && (priv->gl_version >= 30 || priv->has_unpack_subimage)))
{
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / 4);
- if (priv->use_es)
- glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
- data);
- else
- glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
- data);
+ glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, data);
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
}
else
{
int i;
-
- if (priv->use_es)
- {
- glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
- for (i = 0; i < height; i++)
- glTexSubImage2D (texture_target, 0, 0, i, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, data + (i * stride));
- }
- else
- {
- glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
-
- for (i = 0; i < height; i++)
- glTexSubImage2D (texture_target, 0, 0, i, width, 1, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data + (i * stride));
- }
+ glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, NULL);
+ for (i = 0; i < height; i++)
+ glTexSubImage2D (texture_target, 0, 0, i, width, 1, gl_format, gl_type, data + (i * stride));
}
+
+ g_free (copy);
}
static gboolean
#include "gdkglcontext.h"
#include "gdkdrawcontextprivate.h"
+#include "gdkmemorytexture.h"
G_BEGIN_DECLS
int width,
int height,
int stride,
+ GdkMemoryFormat data_format,
guint texture_target);
GdkGLContextPaintData * gdk_gl_context_get_paint_data (GdkGLContext *context);
gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext *context);
#include "gskgltextureatlasprivate.h"
#include "gdk/gdkglcontextprivate.h"
+#include "gdk/gdkmemorytextureprivate.h"
#include <graphene.h>
#include <cairo.h>
GskGLCachedGlyph *value)
{
GskImageRegion r;
+ guchar *pixel_data;
+ guchar *free_data = NULL;
+ guint gl_format;
+ guint gl_type;
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
"Uploading glyph %d",
glBindTexture (GL_TEXTURE_2D, value->texture_id);
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
- glTexSubImage2D (GL_TEXTURE_2D, 0, r.x, r.y, r.width, r.height,
- GL_RGBA, GL_UNSIGNED_BYTE,
- r.data);
+ {
+ pixel_data = free_data = g_malloc (r.width * r.height * 4);
+ gdk_memory_convert (pixel_data, r.width * 4,
+ GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+ r.data, r.width * 4,
+ GDK_MEMORY_DEFAULT, r.width, r.height);
+ gl_format = GL_RGBA;
+ gl_type = GL_UNSIGNED_BYTE;
+ }
else
- glTexSubImage2D (GL_TEXTURE_2D, 0, r.x, r.y, r.width, r.height,
- GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
- r.data);
+ {
+ pixel_data = r.data;
+ gl_format = GL_BGRA;
+ gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+
+ glTexSubImage2D (GL_TEXTURE_2D, 0, r.x, r.y, r.width, r.height,
+ gl_format, gl_type, pixel_data);
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
g_free (r.data);
+ g_free (free_data);
}
gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
#include "gskgliconcacheprivate.h"
#include "gskgltextureatlasprivate.h"
#include "gdk/gdktextureprivate.h"
+#include "gdk/gdkmemorytextureprivate.h"
#include "gdk/gdkglcontextprivate.h"
#include <epoxy/gl.h>
int packed_y = 0;
cairo_surface_t *surface;
unsigned char *surface_data;
+ unsigned char *pixel_data;
+ guchar *free_data = NULL;
guint gl_format;
+ guint gl_type;
gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
"Uploading texture");
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
- gl_format = GL_RGBA;
+ {
+ pixel_data = free_data = g_malloc (width * height * 4);
+ gdk_memory_convert (pixel_data, width * 4,
+ GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+ surface_data, cairo_image_surface_get_stride (surface),
+ GDK_MEMORY_DEFAULT, width, height);
+ gl_format = GL_RGBA;
+ gl_type = GL_UNSIGNED_BYTE;
+ }
else
- gl_format = GL_BGRA;
+ {
+ pixel_data = surface_data;
+ gl_format = GL_BGRA;
+ gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x + 1, packed_y + 1,
width, height,
- gl_format,
- GL_UNSIGNED_BYTE,
- surface_data);
+ gl_format, gl_type,
+ pixel_data);
/* Padding top */
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x + 1, packed_y,
width, 1,
- gl_format, GL_UNSIGNED_BYTE,
- surface_data);
+ gl_format, gl_type,
+ pixel_data);
/* Padding left */
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x, packed_y + 1,
1, height,
- gl_format, GL_UNSIGNED_BYTE,
- surface_data);
+ gl_format, gl_type,
+ pixel_data);
/* Padding top left */
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x, packed_y,
1, 1,
- gl_format, GL_UNSIGNED_BYTE,
- surface_data);
+ gl_format, gl_type,
+ pixel_data);
/* Padding right */
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x + width + 1, packed_y + 1,
1, height,
- gl_format, GL_UNSIGNED_BYTE,
- surface_data);
+ gl_format, gl_type,
+ pixel_data);
/* Padding top right */
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x + width + 1, packed_y,
1, 1,
- gl_format, GL_UNSIGNED_BYTE,
- surface_data);
+ gl_format, gl_type,
+ pixel_data);
/* Padding bottom */
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x + 1, packed_y + 1 + height,
width, 1,
- gl_format, GL_UNSIGNED_BYTE,
- surface_data);
+ gl_format, gl_type,
+ pixel_data);
/* Padding bottom left */
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x, packed_y + 1 + height,
1, 1,
- gl_format, GL_UNSIGNED_BYTE,
- surface_data);
+ gl_format, gl_type,
+ pixel_data);
/* Padding bottom right */
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1);
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x + 1 + width, packed_y + 1 + height,
1, 1,
- gl_format, GL_UNSIGNED_BYTE,
- surface_data);
+ gl_format, gl_type,
+ pixel_data);
/* Reset this */
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
*out_icon_data = icon_data;
cairo_surface_destroy (surface);
+ g_free (free_data);
#if 0
{